// 工具函数
class DevToolbox {
    constructor() {
        this.init();
    }

    init() {
        this.bindEvents();
        this.initTabs();
    }

    // 绑定事件
    bindEvents() {
        // 标签页切换
        document.querySelectorAll('.tab-btn').forEach(btn => {
            btn.addEventListener('click', (e) => this.switchTab(e.target.dataset.tab));
        });

        // 密码生成
        document.getElementById('generatePassword').addEventListener('click', () => this.generatePassword());
        document.getElementById('copyPassword').addEventListener('click', () => this.copyToClipboard('generatedPassword'));

        // MD5加密
        document.getElementById('generateMD5').addEventListener('click', () => this.generateMD5());
        document.getElementById('copyMD5').addEventListener('click', () => this.copyToClipboard('md5Result'));

        // Cron表达式
        document.getElementById('generateCron').addEventListener('click', () => this.generateCron());
        document.getElementById('copyCron').addEventListener('click', () => this.copyToClipboard('cronResult'));
        document.getElementById('testCron').addEventListener('click', () => this.testCron());
        
        // 自定义输入框显示/隐藏
        document.getElementById('cronSecond').addEventListener('change', () => this.toggleCustomInput('cronSecond', 'cronSecondCustom'));
        document.getElementById('cronMinute').addEventListener('change', () => this.toggleCustomInput('cronMinute', 'cronMinuteCustom'));
        document.getElementById('cronHour').addEventListener('change', () => this.toggleCustomInput('cronHour', 'cronHourCustom'));
        
        // 快速测试按钮
        document.getElementById('quickTestCron').addEventListener('click', () => this.quickTestCron());

        // JSON格式化
        document.getElementById('formatJSON').addEventListener('click', () => this.formatJSON());
        document.getElementById('compressJSON').addEventListener('click', () => this.compressJSON());
        document.getElementById('validateJSON').addEventListener('click', () => this.validateJSON());
        document.getElementById('copyJSON').addEventListener('click', () => this.copyToClipboard('jsonOutput'));

        // XML格式化
        document.getElementById('formatXML').addEventListener('click', () => this.formatXML());
        document.getElementById('compressXML').addEventListener('click', () => this.compressXML());
        document.getElementById('copyXML').addEventListener('click', () => this.copyToClipboard('xmlOutput'));

        // URL编码
        document.getElementById('encodeURL').addEventListener('click', () => this.encodeURL());
        document.getElementById('decodeURL').addEventListener('click', () => this.decodeURL());
        document.getElementById('copyURL').addEventListener('click', () => this.copyToClipboard('urlOutput'));

        // Base64编码
        document.getElementById('encodeBase64').addEventListener('click', () => this.encodeBase64());
        document.getElementById('decodeBase64').addEventListener('click', () => this.decodeBase64());
        document.getElementById('copyBase64').addEventListener('click', () => this.copyToClipboard('base64Output'));

        // 格式化工具子标签切换
        document.querySelectorAll('.format-tab-btn').forEach(btn => {
            btn.addEventListener('click', () => this.switchFormatTab(btn.dataset.target));
        });
    }

    // 初始化标签页
    initTabs() {
        this.switchTab('password');
    }

    // 切换标签页
    switchTab(tabName) {
        // 移除所有活动状态
        document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
        document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));

        // 添加活动状态
        document.querySelector(`[data-tab="${tabName}"]`).classList.add('active');
        document.getElementById(tabName).classList.add('active');
    }

    // 切换格式化工具子标签页
    switchFormatTab(tabName) {
        // 移除所有格式化标签的活动状态
        document.querySelectorAll('.format-tab-btn').forEach(btn => btn.classList.remove('active'));
        document.querySelectorAll('.format-tab-content').forEach(content => content.classList.remove('active'));

        // 添加活动状态
        document.querySelector(`[data-target="${tabName}"]`).classList.add('active');
        document.getElementById(tabName).classList.add('active');
    }

    // 密码生成
    generatePassword() {
        const length = parseInt(document.getElementById('passwordLength').value);
        const includeNumbers = document.getElementById('includeNumbers').checked;
        const includeLowercase = document.getElementById('includeLowercase').checked;
        const includeUppercase = document.getElementById('includeUppercase').checked;
        const includeSymbols = document.getElementById('includeSymbols').checked;

        let charset = '';
        if (includeNumbers) charset += '0123456789';
        if (includeLowercase) charset += 'abcdefghijklmnopqrstuvwxyz';
        if (includeUppercase) charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        if (includeSymbols) charset += '!@#$%^&*()_+-=[]{}|;:,.<>?';

        if (!charset) {
            this.showMessage('请至少选择一种字符类型', 'error');
            return;
        }

        let password = '';
        for (let i = 0; i < length; i++) {
            password += charset.charAt(Math.floor(Math.random() * charset.length));
        }

        document.getElementById('generatedPassword').value = password;
    }

    // MD5加密
    generateMD5() {
        const input = document.getElementById('md5Input').value;
        if (!input) {
            this.showMessage('请输入要加密的文本', 'error');
            return;
        }

        const md5Type = document.querySelector('input[name="md5Type"]:checked').value;
        const uppercase = document.getElementById('md5Uppercase').checked;

        let hash = this.md5(input);
        if (md5Type === '16') {
            hash = hash.substring(8, 24);
        }
        if (uppercase) {
            hash = hash.toUpperCase();
        }

        document.getElementById('md5Result').value = hash;
    }

    // MD5算法实现
    md5(string) {
        function md5cycle(x, k) {
            var a = x[0], b = x[1], c = x[2], d = x[3];
            a = ff(a, b, c, d, k[0], 7, -680876936);
            d = ff(d, a, b, c, k[1], 12, -389564586);
            c = ff(c, d, a, b, k[2], 17, 606105819);
            b = ff(b, c, d, a, k[3], 22, -1044525330);
            a = ff(a, b, c, d, k[4], 7, -176418897);
            d = ff(d, a, b, c, k[5], 12, 1200080426);
            c = ff(c, d, a, b, k[6], 17, -1473231341);
            b = ff(b, c, d, a, k[7], 22, -45705983);
            a = ff(a, b, c, d, k[8], 7, 1770035416);
            d = ff(d, a, b, c, k[9], 12, -1958414417);
            c = ff(c, d, a, b, k[10], 17, -42063);
            b = ff(b, c, d, a, k[11], 22, -1990404162);
            a = ff(a, b, c, d, k[12], 7, 1804603682);
            d = ff(d, a, b, c, k[13], 12, -40341101);
            c = ff(c, d, a, b, k[14], 17, -1502002290);
            b = ff(b, c, d, a, k[15], 22, 1236535329);
            a = gg(a, b, c, d, k[1], 5, -165796510);
            d = gg(d, a, b, c, k[6], 9, -1069501632);
            c = gg(c, d, a, b, k[11], 14, 643717713);
            b = gg(b, c, d, a, k[0], 20, -373897302);
            a = gg(a, b, c, d, k[5], 5, -701558691);
            d = gg(d, a, b, c, k[10], 9, 38016083);
            c = gg(c, d, a, b, k[15], 14, -660478335);
            b = gg(b, c, d, a, k[4], 20, -405537848);
            a = gg(a, b, c, d, k[9], 5, 568446438);
            d = gg(d, a, b, c, k[14], 9, -1019803690);
            c = gg(c, d, a, b, k[3], 14, -187363961);
            b = gg(b, c, d, a, k[8], 20, 1163531501);
            a = gg(a, b, c, d, k[13], 5, -1444681467);
            d = gg(d, a, b, c, k[2], 9, -51403784);
            c = gg(c, d, a, b, k[7], 14, 1735328473);
            b = gg(b, c, d, a, k[12], 20, -1926607734);
            a = hh(a, b, c, d, k[5], 4, -378558);
            d = hh(d, a, b, c, k[8], 11, -2022574463);
            c = hh(c, d, a, b, k[11], 16, 1839030562);
            b = hh(b, c, d, a, k[14], 23, -35309556);
            a = hh(a, b, c, d, k[1], 4, -1530992060);
            d = hh(d, a, b, c, k[4], 11, 1272893353);
            c = hh(c, d, a, b, k[7], 16, -155497632);
            b = hh(b, c, d, a, k[10], 23, -1094730640);
            a = hh(a, b, c, d, k[13], 4, 681279174);
            d = hh(d, a, b, c, k[0], 11, -358537222);
            c = hh(c, d, a, b, k[3], 16, -722521979);
            b = hh(b, c, d, a, k[6], 23, 76029189);
            a = hh(a, b, c, d, k[9], 4, -640364487);
            d = hh(d, a, b, c, k[12], 11, -421815835);
            c = hh(c, d, a, b, k[15], 16, 530742520);
            b = hh(b, c, d, a, k[2], 23, -995338651);
            a = ii(a, b, c, d, k[0], 6, -198630844);
            d = ii(d, a, b, c, k[7], 10, 1126891415);
            c = ii(c, d, a, b, k[14], 15, -1416354905);
            b = ii(b, c, d, a, k[5], 21, -57434055);
            a = ii(a, b, c, d, k[12], 6, 1700485571);
            d = ii(d, a, b, c, k[3], 10, -1894986606);
            c = ii(c, d, a, b, k[10], 15, -1051523);
            b = ii(b, c, d, a, k[1], 21, -2054922799);
            a = ii(a, b, c, d, k[8], 6, 1873313359);
            d = ii(d, a, b, c, k[15], 10, -30611744);
            c = ii(c, d, a, b, k[6], 15, -1560198380);
            b = ii(b, c, d, a, k[13], 21, 1309151649);
            a = ii(a, b, c, d, k[4], 6, -145523070);
            d = ii(d, a, b, c, k[11], 10, -1120210379);
            c = ii(c, d, a, b, k[2], 15, 718787259);
            b = ii(b, c, d, a, k[9], 21, -343485551);
            x[0] = add32(a, x[0]);
            x[1] = add32(b, x[1]);
            x[2] = add32(c, x[2]);
            x[3] = add32(d, x[3]);
        }

        function cmn(q, a, b, x, s, t) {
            a = add32(add32(a, q), add32(x, t));
            return add32((a << s) | (a >>> (32 - s)), b);
        }

        function ff(a, b, c, d, x, s, t) {
            return cmn((b & c) | ((~b) & d), a, b, x, s, t);
        }

        function gg(a, b, c, d, x, s, t) {
            return cmn((b & d) | (c & (~d)), a, b, x, s, t);
        }

        function hh(a, b, c, d, x, s, t) {
            return cmn(b ^ c ^ d, a, b, x, s, t);
        }

        function ii(a, b, c, d, x, s, t) {
            return cmn(c ^ (b | (~d)), a, b, x, s, t);
        }

        function md51(s) {
            var n = s.length,
                state = [1732584193, -271733879, -1732584194, 271733878], i;
            for (i = 64; i <= s.length; i += 64) {
                md5cycle(state, md5blk(s.substring(i - 64, i)));
            }
            s = s.substring(i - 64);
            var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
            for (i = 0; i < s.length; i++)
                tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
            tail[i >> 2] |= 0x80 << ((i % 4) << 3);
            if (i > 55) {
                md5cycle(state, tail);
                for (i = 0; i < 16; i++) tail[i] = 0;
            }
            tail[14] = n * 8;
            md5cycle(state, tail);
            return state;
        }

        function md5blk(s) {
            var md5blks = [], i;
            for (i = 0; i < 64; i += 4) {
                md5blks[i >> 2] = s.charCodeAt(i)
                    + (s.charCodeAt(i + 1) << 8)
                    + (s.charCodeAt(i + 2) << 16)
                    + (s.charCodeAt(i + 3) << 24);
            }
            return md5blks;
        }

        var hex_chr = '0123456789abcdef'.split('');

        function rhex(n) {
            var s = '', j = 0;
            for (; j < 4; j++)
                s += hex_chr[(n >> (j * 8 + 4)) & 0x0F]
                    + hex_chr[(n >> (j * 8)) & 0x0F];
            return s;
        }

        function hex(x) {
            for (var i = 0; i < x.length; i++)
                x[i] = rhex(x[i]);
            return x.join('');
        }

        function add32(a, b) {
            return (a + b) & 0xFFFFFFFF;
        }

        return hex(md51(string));
    }

    // 切换自定义输入框显示
    toggleCustomInput(selectId, customInputId) {
        const select = document.getElementById(selectId);
        const customInput = document.getElementById(customInputId);
        
        if (select.value === 'custom') {
            customInput.style.display = 'block';
        } else {
            customInput.style.display = 'none';
            customInput.value = '';
        }
    }

    // Cron表达式生成
    generateCron() {
        let second = document.getElementById('cronSecond').value || '*';
        let minute = document.getElementById('cronMinute').value || '*';
        let hour = document.getElementById('cronHour').value || '*';
        const day = document.getElementById('cronDay').value || '*';
        const month = document.getElementById('cronMonth').value || '*';
        const week = document.getElementById('cronWeek').value || '?';

        // 处理自定义值
        if (second === 'custom') {
            second = document.getElementById('cronSecondCustom').value || '*';
        }
        if (minute === 'custom') {
            minute = document.getElementById('cronMinuteCustom').value || '*';
        }
        if (hour === 'custom') {
            hour = document.getElementById('cronHourCustom').value || '*';
        }

        const cronExpression = `${second} ${minute} ${hour} ${day} ${month} ${week}`;
        document.getElementById('cronResult').value = cronExpression;
    }

    // 快速测试Cron表达式
    quickTestCron() {
        const cronExpression = document.getElementById('cronResult').value;
        if (!cronExpression) {
            this.showMessage('请先生成Cron表达式', 'error');
            return;
        }
        
        // 将表达式复制到测试框
        document.getElementById('cronTest').value = cronExpression;
        
        // 执行测试
        this.testCron();
    }

    // Cron表达式测试
    testCron() {
        const cronExpression = document.getElementById('cronTest').value;
        if (!cronExpression) {
            this.showMessage('请输入Cron表达式', 'error');
            return;
        }

        try {
            // 简单的Cron表达式验证
            const parts = cronExpression.trim().split(/\s+/);
            if (parts.length !== 6) {
                throw new Error('Cron表达式应包含6个部分（秒 分 时 日 月 周）');
            }

            // 计算下5次执行时间
            const nextTimes = this.calculateNextCronTimes(cronExpression, 5);
            
            let resultHtml = '<div class="success-message">表达式格式正确</div>';
            resultHtml += '<div style="margin-top: 10px;"><strong>下5次执行时间:</strong></div>';
            resultHtml += '<div class="cron-time-list">';
            nextTimes.forEach((time, index) => {
                resultHtml += `<div class="cron-time-item">`;
                resultHtml += `<div class="cron-time-index">${index + 1}</div>`;
                resultHtml += `<div class="cron-time-value">${time}</div>`;
                resultHtml += `</div>`;
            });
            resultHtml += '</div>';
            
            document.getElementById('cronTestResult').innerHTML = resultHtml;
        } catch (error) {
            document.getElementById('cronTestResult').innerHTML = `
                <div class="error-message">
                    ${error.message}
                </div>
            `;
        }
    }

    // 计算Cron表达式的下N次执行时间
    calculateNextCronTimes(cronExpression, count) {
        const times = [];
        const now = new Date();
        let currentTime = new Date(now);
        
        // 简化的Cron计算逻辑
        const parts = cronExpression.split(' ');
        const [second, minute, hour, day, month, week] = parts;
        
        for (let i = 0; i < count; i++) {
            // 增加时间间隔来模拟下次执行
            if (minute === '*' && hour === '*') {
                // 每分钟执行
                currentTime = new Date(currentTime.getTime() + 60 * 1000);
            } else if (hour === '*') {
                // 每小时的指定分钟执行
                currentTime = new Date(currentTime.getTime() + 60 * 60 * 1000);
            } else if (day === '*') {
                // 每天的指定时间执行
                currentTime = new Date(currentTime.getTime() + 24 * 60 * 60 * 1000);
            } else {
                // 其他情况，默认每天执行
                currentTime = new Date(currentTime.getTime() + 24 * 60 * 60 * 1000);
            }
            
            // 调整到指定的秒、分、时
            if (second !== '*') {
                const sec = parseInt(second) || 0;
                currentTime.setSeconds(sec);
            }
            if (minute !== '*' && !minute.includes('/')) {
                const min = parseInt(minute) || 0;
                currentTime.setMinutes(min);
            }
            if (hour !== '*' && !hour.includes('/')) {
                const hr = parseInt(hour) || 0;
                currentTime.setHours(hr);
            }
            
            times.push(currentTime.toLocaleString('zh-CN', {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit'
            }));
        }
        
        return times;
    }

    // JSON格式化
    formatJSON() {
        const input = document.getElementById('jsonInput').value;
        if (!input) {
            this.showMessage('请输入JSON字符串', 'error');
            return;
        }

        try {
            const parsed = JSON.parse(input);
            const formatted = JSON.stringify(parsed, null, 2);
            document.getElementById('jsonOutput').value = formatted;
        } catch (error) {
            document.getElementById('jsonOutput').value = `JSON格式错误: ${error.message}`;
        }
    }

    // JSON压缩
    compressJSON() {
        const input = document.getElementById('jsonInput').value;
        if (!input) {
            this.showMessage('请输入JSON字符串', 'error');
            return;
        }

        try {
            const parsed = JSON.parse(input);
            const compressed = JSON.stringify(parsed);
            document.getElementById('jsonOutput').value = compressed;
        } catch (error) {
            document.getElementById('jsonOutput').value = `JSON格式错误: ${error.message}`;
        }
    }

    // JSON验证
    validateJSON() {
        const input = document.getElementById('jsonInput').value;
        if (!input) {
            this.showMessage('请输入JSON字符串', 'error');
            return;
        }

        try {
            JSON.parse(input);
            document.getElementById('jsonOutput').value = 'JSON格式正确 ✓';
        } catch (error) {
            document.getElementById('jsonOutput').value = `JSON格式错误: ${error.message}`;
        }
    }

    // XML格式化
    formatXML() {
        const input = document.getElementById('xmlInput').value;
        if (!input) {
            this.showMessage('请输入XML字符串', 'error');
            return;
        }

        try {
            const formatted = this.formatXMLString(input);
            document.getElementById('xmlOutput').value = formatted;
        } catch (error) {
            document.getElementById('xmlOutput').value = `XML格式错误: ${error.message}`;
        }
    }

    // XML压缩
    compressXML() {
        const input = document.getElementById('xmlInput').value;
        if (!input) {
            this.showMessage('请输入XML字符串', 'error');
            return;
        }

        const compressed = input.replace(/\s+/g, ' ').replace(/> </g, '><').trim();
        document.getElementById('xmlOutput').value = compressed;
    }

    // XML格式化辅助函数
    formatXMLString(xml) {
        const PADDING = ' '.repeat(2);
        const reg = /(>)(<)(\/*)/g;
        let pad = 0;

        xml = xml.replace(reg, '$1\r\n$2$3');

        return xml.split('\r\n').map((node) => {
            let indent = 0;
            if (node.match(/.+<\/\w[^>]*>$/)) {
                indent = 0;
            } else if (node.match(/^<\/\w/) && pad > 0) {
                pad -= 1;
            } else if (node.match(/^<\w[^>]*[^/]>.*$/)) {
                indent = 1;
            } else {
                indent = 0;
            }

            const padding = PADDING.repeat(pad);
            pad += indent;

            return padding + node;
        }).join('\r\n');
    }

    // URL编码
    encodeURL() {
        const input = document.getElementById('urlInput').value;
        if (!input) {
            this.showMessage('请输入要编码的URL', 'error');
            return;
        }

        const encoded = encodeURIComponent(input);
        document.getElementById('urlOutput').value = encoded;
    }

    // URL解码
    decodeURL() {
        const input = document.getElementById('urlInput').value;
        if (!input) {
            this.showMessage('请输入要解码的URL', 'error');
            return;
        }

        try {
            const decoded = decodeURIComponent(input);
            document.getElementById('urlOutput').value = decoded;
        } catch (error) {
            document.getElementById('urlOutput').value = `解码错误: ${error.message}`;
        }
    }

    // Base64编码
    encodeBase64() {
        const input = document.getElementById('base64Input').value;
        if (!input) {
            this.showMessage('请输入要编码的文本', 'error');
            return;
        }

        const encoded = btoa(unescape(encodeURIComponent(input)));
        document.getElementById('base64Output').value = encoded;
    }

    // Base64解码
    decodeBase64() {
        const input = document.getElementById('base64Input').value;
        if (!input) {
            this.showMessage('请输入要解码的Base64字符串', 'error');
            return;
        }

        try {
            const decoded = decodeURIComponent(escape(atob(input)));
            document.getElementById('base64Output').value = decoded;
        } catch (error) {
            document.getElementById('base64Output').value = `解码错误: ${error.message}`;
        }
    }

    // 复制到剪贴板
    async copyToClipboard(elementId) {
        const element = document.getElementById(elementId);
        const text = element.value;
        
        if (!text) {
            this.showMessage('没有内容可复制', 'error');
            return;
        }

        try {
            await navigator.clipboard.writeText(text);
            this.showMessage('已复制到剪贴板', 'success');
        } catch (error) {
            // 降级方案
            element.select();
            document.execCommand('copy');
            this.showMessage('已复制到剪贴板', 'success');
        }
    }

    // 显示消息
    showMessage(message, type = 'success') {
        // 移除现有消息
        const existingMessage = document.querySelector('.message');
        if (existingMessage) {
            existingMessage.remove();
        }

        // 创建新消息
        const messageDiv = document.createElement('div');
        messageDiv.className = `message ${type}-message`;
        messageDiv.textContent = message;
        messageDiv.style.position = 'fixed';
        messageDiv.style.top = '10px';
        messageDiv.style.right = '10px';
        messageDiv.style.zIndex = '9999';
        messageDiv.style.padding = '10px 15px';
        messageDiv.style.borderRadius = '4px';
        messageDiv.style.fontSize = '14px';
        messageDiv.style.fontWeight = '500';
        
        if (type === 'success') {
            messageDiv.style.background = '#d4edda';
            messageDiv.style.color = '#155724';
            messageDiv.style.border = '1px solid #c3e6cb';
        } else {
            messageDiv.style.background = '#f8d7da';
            messageDiv.style.color = '#721c24';
            messageDiv.style.border = '1px solid #f5c6cb';
        }

        document.body.appendChild(messageDiv);

        // 3秒后自动移除
        setTimeout(() => {
            if (messageDiv.parentNode) {
                messageDiv.remove();
            }
        }, 3000);
    }
}

// 初始化应用
document.addEventListener('DOMContentLoaded', () => {
    new DevToolbox();
});